#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <FS.h> 

#define FW_VERSION     "0.0.1"
#define BUILD_TIME (__DATE__ " " __TIME__)

DynamicJsonDocument getSysInfo() {
  DynamicJsonDocument doc(1024);

  /* ===== 网络 ===== */
  doc["ip"]           = WiFi.localIP().toString();
  doc["mac"]          = WiFi.macAddress();
  doc["gateway_ip"]   = WiFi.gatewayIP().toString();
  doc["subnet_mask"]  = WiFi.subnetMask().toString();
  doc["dns_ip"]       = WiFi.dnsIP().toString();
  doc["hostname"]     = WiFi.hostname();
  doc["bssid"]        = WiFi.BSSIDstr();
  doc["rssi"]         = WiFi.RSSI();            // dBm
  doc["ssid"]         = WiFi.SSID();
  doc["channel"]      = WiFi.channel();
  doc["wifi_mode"]    = WiFi.getMode();
  doc["wifi_status"]  = WiFi.status();
  doc["softap_ip"]    = WiFi.softAPIP().toString();
  doc["softap_mac"]   = WiFi.softAPmacAddress();
  doc["softap_ssid"]  = WiFi.softAPSSID();

  /* ===== 内存 ===== */
  doc["heap_free"]      = ESP.getFreeHeap();
  doc["heap_max_alloc"] = ESP.getMaxFreeBlockSize();
  doc["heap_frag"]      = ESP.getHeapFragmentation();
  doc["free_stack"]      = ESP.getFreeContStack();

  /* ===== CPU / 芯片 ===== */
  doc["chip_id"]      = ESP.getChipId();        // ESP8266
  doc["cpu_freq"]     = ESP.getCpuFreqMHz();    // MHz
  doc["sdk"]          = ESP.getSdkVersion();

  /* ===== Flash ===== */
  doc["flash_chip_id"]      = ESP.getFlashChipId();
  doc["flash_chip_speed"]   = ESP.getFlashChipSpeed();
  doc["flash_chip_mode"]    = ESP.getFlashChipMode();
  doc["flash_size"]         = ESP.getFlashChipSize(); // 字节
  doc["flash_real"]         = ESP.getFlashChipRealSize(); // 物理大小
  doc["flash_speed"]        = ESP.getFlashChipSpeed();    // Hz
  doc["is_flash_sketch"]    = ESP.checkFlashCRC();
  doc["sketch_md5"]         = ESP.getSketchMD5();
  doc["sketch_size"]        = ESP.getSketchSize();
  doc["free_sketch_space"]  = ESP.getFreeSketchSpace();

  /* ===== 运行时间 ===== */
  doc["uptime_ms"]            = millis();
  doc["vcc"]                  = ESP.getVcc();
  doc["reset_reason"]         = ESP.getResetInfo();
  doc["reset_reason_code"]    = ESP.getResetInfoPtr()->reason;
  doc["build_time"]           = BUILD_TIME;
  doc["version"]              = FW_VERSION;

  /* SPIFFS */
  FSInfo fs_info;
  if (SPIFFS.info(fs_info)) {
    doc["spiffs_total"] = fs_info.totalBytes;
    doc["spiffs_used"] = fs_info.usedBytes;
    doc["spiffs_free"] = fs_info.totalBytes - fs_info.usedBytes;
    doc["spiffs_block_size"] = fs_info.blockSize;
    doc["spiffs_page_size"] = fs_info.pageSize;
    doc["spiffs_max_open_files"] = fs_info.maxOpenFiles;
    doc["spiffs_max_path_length"] = fs_info.maxPathLength;
  } else {
    doc["spiffs_total"] = 0;
    doc["spiffs_used"] = 0;
    doc["spiffs_free"] = 0;
    doc["spiffs_block_size"] = 0;
    doc["spiffs_page_size"] = 0;
    doc["spiffs_max_open_files"] = 0;
    doc["spiffs_max_path_length"] = 0;
  }

  return doc;
}